<?php
    defined('INDEX') or die ('Acesso direto não permitido');
    
    require_once (dirname(__FILE__)."/../request/Request.class.php");
    require_once (dirname(__FILE__)."/FormularioButtonBar.class.php");
    require_once (dirname(__FILE__)."/../application/ApplicationFactory.class.php");
    
    abstract class FormularioBase
    {
        protected $pageTitle     = '';
        
        protected $buttonBar     = null;
        
        protected $disabedButtonBar = false;
        
        protected $pageObject	 = null;
        
        const INFO = 1;
        
        const OK   = 2;
        
        const ERRO = 3;
        
        public function __construct($pageObject)
        {
            $this->buttonBar   = new FormularioButtonBar($this);
            $this->pageObject  = $pageObject;
            
            Application::setCurrentFormularioBase($this);
            
            $this->loadJavascriptFile("js/jquery/jquery-1.4.2.min.js", "afterLoad");
            $this->loadCssFile("templates/default/style.css", "all");
            
            echo $this->printStoredMessage();
        }
        
        public function setDisabledButtonBar ($disabled)
        {
            $this->disabedButtonBar = $disabled;
        }
        
        public function isDisabledButtonBar ()
        {
            return $this->disabedButtonBar;
        }
        
        /**
         * This function store an message in the user session.
         * 
         * @param string $mensagem - the message to store.
         * 
         * @param string $title - the message title.
         * 
         * @param integer $type - the type of message (use FormularioBase constants).
         * 
         * @return void
         */
        public function storeMessage ($mensagem, $title = '', $type)
        {
            if($type < 1 || $type > 3 || !is_numeric($type))
            {
                $type = FormularioBase::INFO;
            }
            
            $content = new stdClass();
            $content->type        = $type;
            $content->mensagem    = $mensagem;
            $content->title       = $title;
            
            $this->getSession()->storeMessage($content);
        }
        
        /**
         * This function prints the stored messages in the user session.
         * 
         * @return string $messageContent
         */
        public function printStoredMessage ()
        {
            $content = ApplicationFactory::getSessionFactory()->getStoredMessage();
            
            if(isset($content))
            {
            	
	            switch ($content->type)
	            {
	            	case FormularioBase::ERRO:
	            	    $class = 'error';
	            	break;
	            	case FormularioBase::OK:
	            	    $class = 'ok';
	            	break;
	            	case FormularioBase::INFO:
	            	    $class = 'info-blue';
	            	break;
	            }
	            
	            $str = "<div class='$class'>";
	            
	            if($content->title)
	            {
	                $str .= "<h3>$content->title</h3>";
	            }
	            
	            $str .= "$content->mensagem";
	            
	            $str .= "</div>";
	            
	            echo $str;
	            ApplicationFactory::getSessionFactory()->destroyStoredMessage();
            }
        }
        
        /**
         * Returns if exists an message stored in the user session.
         * 
         * @return bool $has - true when exists.
         */
        public function hasStoredMessage ()
        {
            return ApplicationFactory::getSessionFactory()->hasStoredMessage();
        }
        
        /**
         * This function force a internal redirect to an URL.
         * 
         * @param string $url - ex: index.php?pagina=xx&acao=xx 
         */
        protected function redirect ($url)
        {
            return header('Location: '.$url);
        }
        
        /**
         * Returns the instance of Request object manager across the 
         * ApplicationFactory object.
         * 
         * @return Request $request
         */
        public function getRequest ()
        {
            return ApplicationFactory::getRequestFactory();
        }

        abstract public function lista ();
        
        abstract public function view ($id);
        
        abstract public function form ($id = '');
        
        abstract public function process ();
        
        abstract public function delete ($id);
        
        /**
         * This function process and call functions by action param
         * defined in the $_GET, $_POST URL.
         * 
         * @return void
         */
        public function processAction ()
        {
        	$acao = null;
        	
        	if(!ApplicationFactory::getRequestFactory()->hasPost())
        	{
        		$acao = ApplicationFactory::getRequestFactory()->get('acao', 'STRING');
        	}
        	else
        	{
        		$acao = ApplicationFactory::getRequestFactory()->post('acao', 'STRING');
        	}
        	
        	// Protect the user dont use 'processAction' action.
        	if($acao == null || $acao == '' || $acao == 'processAction')
        	{
        		$acao = $this->getPageObject()->acao_padrao;
        	}
        	
        	if(method_exists($this, $acao))
        	{
        		$reflection = new ReflectionMethod($this, $acao);
        		
        		if(sizeof($reflection->getParameters()))
        		{
        			// Only pass the 'id' param by generic way.
        			$id = null;
		        	if(!ApplicationFactory::getRequestFactory()->hasPost())
		        	{
		        		$id = ApplicationFactory::getRequestFactory()->get('id', 'STRING');
		        	}
		        	else
		        	{
		        		$id = ApplicationFactory::getRequestFactory()->post('id', 'STRING');
		        	}
		        	
        			return $this->$acao($id);
        		}
        		else
        		{
        			return $this->$acao();
        		}
        	}
        	else
        	{
        		return $this->lista();
        	}
        }
        
        /**
         * Returns an instance of current instantied FormularioBase object.
         * 
         * @return FormularioBase $pageObject
         */
        public function getPageObject ()
        {
        	return $this->pageObject;
        }
        
        /**
         * Sets the title of current page.

         * @param string $title
         * 
         * @return void
         */
        public function setPageTitle ($title)
        {
            $this->pageTitle = $title;
        }
        
        /**
         * Returns the title of current page.
         * 
         * @return string $pageTitle
         */
        public function getPageTitle()
        {
            return $this->pageTitle;
        }
        
        /**
         * @return SessionManager $session
         */
        public function getSession()
        {
            return ApplicationFactory::getSessionFactory();
        }
        
        /**
         * @return FormularioButtonBar
         */
		public function getButtonBar ()
        {
            return $this->buttonBar;
        }
        
        /**
         * This function instantiate and populate an Doctrine_Record object with
         * the form data ($_POST or $_GET).
         * 
         * @param string $className - the name of class.
         * 
         * @param array $dados - the content to populate in object.
         * 
         * @return stdClass $object
         */
        public function populateObjectWithArrayData ($className, $dados = null)
        {
        	if($className != '')
        	{
        		$filename = dirname(__FILE__)."/../../model/".$className.".class.php";
        		
        		if(file_exists($filename) && !is_dir($filename))
        		{
		        	if(class_exists($className))
		        	{
		        		try
		        		{
		        			$object = new $className();
		        			
		        			if(is_array($dados))
		        			{
			        			foreach ($dados as $field => $value)
			        			{
			        				try {
			        					$object->$field = $value;
			        				} catch (Exception $e) {
			        					// Doctrine field exception protection.
			        				}
			        			}
		        			}
		        			
		        			return $object;
		        		} catch (Exception $e) {
		        			die("Erro ao tentar instanciar um objeto da classe [$className].");
		        		}
		        	}
		        	else
		        	{
		        		die("A classe [".$className."] especificada não existe.");
		        	}
        		}
        		else
        		{
        			die("Arquivo da classe [".$className."] não encontrado.");
        		}
        	}
        	else
        	{
        		die("Nenhuma classe especificada para o carregamento automático.");
        	}
        }
        
        /**
         * Returns if the current user has capability to execute an action.
         * 
         * @param string $capability - the name of capability.
         * 
         * @return bool $has - true when have capability.
         */
        protected function hasCapability ($capability)
        {
        	return ApplicationFactory::getCapabilityManagerFactory()->hasCapability($capability);
        }
        
        /**
         * Load an javascript file.
         * 
         * @param string $relativePath
         * 
         * @param string $loadMode - can be afterLoad, beforeLoad or now.
         * 
         * @return string $scriptTag
         */
        protected function loadJavascriptFile ($relativePath, $loadMode = 'afterLoad')
        {
        	echo ApplicationFactory::getHTMLComponentFactory()->loadJavascriptFile($relativePath, $loadMode);
        }
        
        /**
         * This function loads an CSS file to application.
         * 
         * @param string $relativePath
         * 
         * @param string $mediaType
         * 
         * @return void
         */
    	protected function loadCssFile ($relativePath, $mediaType = 'all')
        {
        	echo ApplicationFactory::getHTMLComponentFactory()->loadCssFile($relativePath, $mediaType);
        }
        
        protected function initRichTextEditor ($mode)
        {
        	ApplicationFactory::getHTMLComponentFactory()->loadRichTextEditorFiles();
        	echo '<script type="text/javascript">
        			tinyMCE.init({
						mode : "textareas",
						theme : "simple"
					});
        		</script>';
        }
    }
?>